package com.qfedu.fmmall.service.impl;


import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qfedu.fmmall.dao.CategoryMapper;
import com.qfedu.fmmall.entity.CategoryVo;
import com.qfedu.fmmall.service.CategoryService;
import com.qfedu.fmmall.vo.ResultStatus;
import com.qfedu.fmmall.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public ResultVo listCategories() {
        List<CategoryVo> categoryVos = null;
        try {
            String category = stringRedisTemplate.boundValueOps("category").get();
            if(category != null){
                JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, CategoryVo.class);
                categoryVos = objectMapper.readValue(category,javaType);
            }else{
                //双重验证，防止高并发导致的缓存击穿
                synchronized (this){ //线程锁
                    String doubleData = stringRedisTemplate.boundValueOps("category").get();
                    if(doubleData == null){ //如果redis中没有，就添加数据到redis
                        categoryVos = categoryMapper.selectAllCategories();
                        stringRedisTemplate.boundValueOps("category").set(objectMapper.writeValueAsString(categoryVos));
                    }


                }

            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return new ResultVo(ResultStatus.OK,"success",categoryVos);
    }

    @Override
    public ResultVo selectFirstLevelCategories() {
        List<CategoryVo> categoryVos = categoryMapper.selectFirstLevelCategories();
        return new ResultVo(ResultStatus.OK,"success",categoryVos);
    }
}
